package com.rc.saas.tenant.service.operator;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rc.saas.tenant.base.BaseSearch;
import com.rc.saas.tenant.common.component.UidGenerator;
import com.rc.saas.tenant.common.constant.CommonConstant;
import com.rc.saas.tenant.common.constant.WebConstant;
import com.rc.saas.tenant.common.utils.MD5Utils;
import com.rc.saas.tenant.common.vo.TResponse;
import com.rc.saas.tenant.mapper.operator.TenantOperatorMapper;
import com.rc.saas.tenant.mapper.operator.TenantOperatorStationMapper;
import com.rc.saas.tenant.model.acct.AcctWithdrawApply;
import com.rc.saas.tenant.model.acct.AcctWithdrawOrder;
import com.rc.saas.tenant.model.acct.TenantOperatorAcctSetting;
import com.rc.saas.tenant.model.operator.TenantOperatorStation;
import com.rc.saas.tenant.model.operator.TenantOperatorStationExample;
import com.rc.saas.tenant.model.tenant.*;
import com.rc.saas.tenant.model.operator.TenantOperator;
import com.rc.saas.tenant.model.operator.TenantOperatorExample;
import com.rc.saas.tenant.search.acct.AcctTenantOperatorElecStationSearch;
import com.rc.saas.tenant.search.operator.OperatorSearch;
import com.rc.saas.tenant.service.acct.AcctWithdrawOrderService;
import com.rc.saas.tenant.service.hlht.HlhtTenantOpenStationService;
import com.rc.saas.tenant.service.tenant.TenantService;
import com.rc.saas.tenant.service.tenant.TenantSettingService;
import com.rc.saas.tenant.service.tenant.TenantUserService;
import com.rc.saas.tenant.vo.operator.OperatorElecStationVo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.validator.internal.util.stereotypes.Lazy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * Created by sven on 2019/9/18
 */
@Service
public class TenantOperatorServiceImpl implements TenantOperatorService {
    private static Logger logger = LogManager.getLogger(TenantOperatorServiceImpl.class);

    @Autowired
    private TenantOperatorMapper tenantOperatorMapper;

    @Autowired
    private TenantUserService tenantUserService;

    @Autowired
    private TenantOperatorStationMapper tenantOperatorStationMapper;

    @Autowired
    private HlhtTenantOpenStationService hlhtTenantOpenStationService;

    @Autowired
    private TenantService tenantService;

    @Autowired
    private UidGenerator uidGenerator;

    @Autowired
    @Lazy
    private TenantSettingService tenantSettingService;

    @Autowired
    private AcctWithdrawOrderService acctWithdrawOrderService;


    public TenantOperatorMapper getMapper() {
        return tenantOperatorMapper;
    }

    @Override
    public void insertOperatorAndUser(TenantOperator operator, TenantUser user) {
        operator.setTenantCode(user.getTenantCode());
        //登录帐号和密码转为小写
        operator.setLoginName(operator.getLoginName().toLowerCase());
        operator.setPassword(operator.getPassword().toLowerCase());
        String saltPassword = MD5Utils.encrypt(operator.getLoginName(), operator.getPassword());

        operator.setPassword(saltPassword);
        //保存运营商资料
        operator.setStatus(WebConstant.STATUS_ZERO);
        operator.setCreatedTime(new Date());
        tenantOperatorMapper.insertSelective(operator);

        //保存登录帐户资料
        TenantUser tenantUser = new TenantUser();
        tenantUser.setTenantCode(user.getTenantCode());
        tenantUser.setTenantOperatorCode(operator.getTenantOperatorCode());
        tenantUser.setLoginName(operator.getLoginName());

        //用户类型（0 运营商 1 分销商 2企业用户）默认0
        tenantUser.setUserType(WebConstant.STATUS_ONE);
        tenantUser.setMobile(operator.getPhone());
        tenantUser.setStatus(WebConstant.STATUS_ZERO);

        //六位随机数密码
        //int randMun = (int) ((Math.random() * 9 + 1) * 100000);
        //String password = String.valueOf(randMun);
        //logger.info("初始密码,:{},:{},:{}", tenant.getLoginName(), tenant.getPhone(), password);

        //密码加密保存
        tenantUser.setPassword(saltPassword);
        tenantUserService.insertSelective(tenantUser);
    }

    @Override
    public void updateOperatorAndUserStatus(TenantOperator tenantOperator, TenantUser tenantUser) {
        //状态 0:正常 1:暂停 默认0
        //TenantOperator tenantOperator = tenantOperatorMapper.selectByPrimaryKey(tenantOperatorCode);
        //TenantUser tenantUser = tenantUserService.selectByLoginName(tenantOperatorCode);

        if (tenantOperator != null && WebConstant.STATUS_ZERO.equals(tenantOperator.getStatus())) { //冻结
            tenantOperator.setStatus(WebConstant.STATUS_ONE);
            tenantOperatorMapper.updateByPrimaryKeySelective(tenantOperator);

            tenantUser.setStatus(WebConstant.STATUS_ONE);
            tenantUserService.updateByPrimaryKey(tenantUser);
        } else if (tenantOperator != null && WebConstant.STATUS_ONE.equals(tenantOperator.getStatus())) {//解冻
            tenantOperator.setStatus(WebConstant.STATUS_ZERO);
            tenantOperatorMapper.updateByPrimaryKey(tenantOperator);

            tenantUser.setStatus(WebConstant.STATUS_ZERO);
            tenantUserService.updateByPrimaryKeySelective(tenantUser);
        }
    }

    @Override
    public String updateOperatorAndUserPassword(TenantOperator tenantOperator, TenantUser tenantUser, String password) {
        String saltPassword = MD5Utils.encrypt(tenantOperator.getLoginName(), password);

        logger.info("重置密码:{},:{}", tenantOperator.getLoginName(), password);

        //保存运营商资料
        TenantOperator newTenantOperator = new TenantOperator();
        newTenantOperator.setTenantOperatorCode(tenantOperator.getTenantOperatorCode());
        newTenantOperator.setPassword(saltPassword);
        tenantOperatorMapper.updateByPrimaryKeySelective(newTenantOperator);

        //保存登录帐户资料
        TenantUser newTenantUser = new TenantUser();
        newTenantUser.setTenantUserId(tenantUser.getTenantUserId());
        newTenantUser.setPassword(saltPassword);
        tenantUserService.updateByPrimaryKeySelective(newTenantUser);

        return password;
    }

    @Override
    public TenantOperator selectByLoginName(String loginName) {
        TenantOperatorExample example = new TenantOperatorExample();
        example.createCriteria().andLoginNameEqualTo(loginName);
        List<TenantOperator> list = tenantOperatorMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public TenantOperator checkLoginNameExist(String loginName) {
        TenantOperatorExample example = new TenantOperatorExample();
        example.createCriteria().andLoginNameEqualTo(loginName);
        List<TenantOperator> list = tenantOperatorMapper.selectByExample(example);
        if (list.size() != 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public TenantOperator checkPhoneExist(String phone) {
        TenantOperatorExample example = new TenantOperatorExample();
        example.createCriteria().andPhoneEqualTo(phone);
        List<TenantOperator> list = tenantOperatorMapper.selectByExample(example);
        if (list.size() != 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public TenantOperator checkOperatorCodeExist(String operatorCode) {
        TenantOperatorExample example = new TenantOperatorExample();
        example.createCriteria().andTenantOperatorCodeEqualTo(operatorCode);
        List<TenantOperator> list = tenantOperatorMapper.selectByExample(example);
        if (list.size() != 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public PageInfo<TenantOperator> listPageOperator(TenantOperatorExample example, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<TenantOperator> list = tenantOperatorMapper.selectByExample(example);
        return new PageInfo<TenantOperator>(list);
    }

    @Override
    public List<TenantOperator> listOperatorByTenantCode(String tenantCode) {
        TenantOperatorExample example = new TenantOperatorExample();
        example.createCriteria().andTenantCodeEqualTo(tenantCode);
        List<TenantOperator> tenantOperators = tenantOperatorMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(tenantOperators)) {
            return tenantOperators;
        }
        return null;
    }

    @Override
    public PageInfo<OperatorElecStationVo> listPageOperatorElecStation(BaseSearch baseSearch) {
        PageHelper.startPage(baseSearch.getOffset(), baseSearch.getLimit());
        List<OperatorElecStationVo> list = tenantOperatorMapper.listPageOperatorElecStation(baseSearch.getTenantOperatorCode());
        return new PageInfo<OperatorElecStationVo>(list);
    }

    @Override
    public void updatebatchType(List<Long> operatorStationIdList, String govtHlhtType, String tenantOperatorCode) {
        TenantOperatorStation tenantOperatorStation = new TenantOperatorStation();
        tenantOperatorStation.setGovtHlhtType(govtHlhtType);
        TenantOperatorStationExample example = new TenantOperatorStationExample();
        example.createCriteria().andOperatorStationIdIn(operatorStationIdList);
        tenantOperatorStationMapper.updateByExampleSelective(tenantOperatorStation, example);
        if ("1".equals(govtHlhtType)) {
            hlhtTenantOpenStationService.updateTenantOperatorCodeByStationId(operatorStationIdList, tenantOperatorCode);
        } else {
            hlhtTenantOpenStationService.updateTenantOperatorCodeByStationId(operatorStationIdList, null);
        }
    }

    @Override
    public List<TenantOperator> listExportTenantOperator(OperatorSearch search) {
        return tenantOperatorMapper.listTenantOperator(search);
    }

    @Override
    public PageInfo<TenantOperator> listPageTenantOperator(OperatorSearch search) {
        PageHelper.startPage(search.getOffset(), search.getLimit());
        List<TenantOperator> list = tenantOperatorMapper.listTenantOperator(search);
        return new PageInfo<TenantOperator>(list);
    }

    @Override
    public PageInfo<OperatorElecStationVo> listPageAcctTenantOperatorElecStation(AcctTenantOperatorElecStationSearch acctTenantOperatorElecStationSearch) {
        PageHelper.startPage(acctTenantOperatorElecStationSearch.getOffset(), acctTenantOperatorElecStationSearch.getLimit());
        List<OperatorElecStationVo> list = tenantOperatorStationMapper.listPageAcctTenantOperatorElecStation(acctTenantOperatorElecStationSearch);
        return new PageInfo<OperatorElecStationVo>(list);
    }

    @Override
    public List<OperatorElecStationVo> exportAcctTenantOperatorElecStation(AcctTenantOperatorElecStationSearch acctTenantOperatorElecStationSearch) {
        return tenantOperatorStationMapper.listPageAcctTenantOperatorElecStation(acctTenantOperatorElecStationSearch);
    }

    @Override
    public TResponse bankTransPayWallet(TenantOperator tenantOperator, AcctWithdrawApply acctWithdrawApply, TenantOperatorAcctSetting acctSetting) {
        //        if (alipayTransPayWalletVo.getTransAmount().compareTo(BigDecimal.ZERO) <= 0) {
//            logger.error("转账金额不合法:{}", alipayTransPayWalletVo.getTransAmount());
//            return TResponse.FAIL("转账金额不合法:" + alipayTransPayWalletVo.getTransAmount());
//        }

        //根据不同的运营商简码生成充值订单号
        Tenant tenant = tenantService.selectByPrimaryKey(tenantOperator.getTenantCode());
        String outTradeNo = uidGenerator.genAlipayTransferOutBizNo(tenant.getTenantPrefix(), tenantOperator.getTenantOperatorCode(), CommonConstant.MT_TRANSFER_PREFIX);
        if (outTradeNo == null) {
            return TResponse.FAIL("无法生成转账单号");
        }

//        TenantSetting tenantSetting = tenantSettingService.selectByPrimaryKey(tenantOperator.getTenantCode());

        //1 查询自己余额是否足够
//        AlipayFundAccountQueryResponse queryResponse = accountQuery(assembleClientParams(tenantSetting), alipayTransPayWalletVo, tenantSetting);
//        if (queryResponse == null || !queryResponse.isSuccess()) {
//            logger.error("账户余额查询接口异常:{}", queryResponse.getBody());
//            return TResponse.FAIL("账户余额查询接口异常");
//        }

        //账户可用余额，单位元，精确到小数点后两位。示例值：26.45
//        logger.warn("appId:" + aliPayConfig.getAppId() + ":账户可用余额:{}元", queryResponse.getAvailableAmount());
//        if (alipayTransPayWalletVo.getTransAmount().compareTo(new BigDecimal(queryResponse.getAvailableAmount())) > 0) {
//            logger.error("账户余额不足,可用余额:{},本次申请转帐金额:{}", queryResponse.getAvailableAmount(), alipayTransPayWalletVo.getTransAmount());
//            return TResponse.FAIL("账户余额不足");
//        }

        //生成转帐单
        AcctWithdrawOrder acctWithdrawOrder = new AcctWithdrawOrder();
        acctWithdrawOrder.setTenantCode(tenantOperator.getTenantCode());
        acctWithdrawOrder.setTenantOperatorCode(tenantOperator.getTenantOperatorCode());

        //收款账户类型,0 对公（在金融机构开设的公司账户）,如果银行卡为对公，必须传递省市支行信息或者联行号 1对私（在金融机构开设的个人账户）
        acctWithdrawOrder.setAccountType("1");
//        //支付宝的会员ID
        acctWithdrawOrder.setAlipayUserId("银行卡转账试用");

        //提现类型 0平台转帐 1网银转帐 默认0
        acctWithdrawOrder.setTransferType("0");
        //申请来源 0运营商后台  默认0
        acctWithdrawOrder.setTransferSource("0");
        acctWithdrawOrder.setTransferBy("1");

        acctWithdrawOrder.setOutTradeNo(outTradeNo);
        acctWithdrawOrder.setWithdrawApplyId(acctWithdrawApply.getWithdrawApplyId());//申请单ID
        acctWithdrawOrder.setAmount(acctWithdrawApply.getWithdrawAmount());//单位（元）

        //到帐状态 0未到帐  1已到帐 2转账失败 默认0
        acctWithdrawOrder.setStatus("0");
        acctWithdrawOrder.setCreatedTime(new Date());
        acctWithdrawOrderService.insertSelectiveReturnId(acctWithdrawOrder);

//        logger.info(tenantOperator.getTenantCode() + "-" + tenantOperator.getTenantOperatorCode() + ":准备发起单笔转账至支付宝接口:{}", alipayTransPayWalletVo.toString());

        try {
            // 2 创建AlipayClient实例
//            AlipayClient alipayClient = new DefaultAlipayClient(assembleClientParams(tenantSetting));

            // 3 创建使用的Open API对应的Request请求对象
//            AlipayFundTransUniTransferRequest uniTransferRequest = uniTransfer(outTradeNo, tenantOperator, alipayTransPayWalletVo, acctSetting);

            // 4 发起请求并处理响应
//            AlipayFundTransUniTransferResponse transferResponse = alipayClient.certificateExecute(uniTransferRequest);

            //如果转账接口同步返回的 status 属性为 SUCCESS 则表示转账成功；同步调用若发生超时等异常情况，可以通过异步通知或者调用转账查询接口做主动查询
//            if (!transferResponse.isSuccess()) {
//                logger.error("支付宝转账失败:{},:{},:{}", transferResponse.getMsg(), transferResponse.getSubMsg(), transferResponse.getBody());
//                return TResponse.FAIL("支付宝转账失败");
//            }

            //6 查转账单据状态
//            AlipayFundTransCommonQueryResponse commonQueryResponse = queryTransferInfo(assembleClientParams(tenantSetting), transferResponse);
//            if (commonQueryResponse == null || !commonQueryResponse.isSuccess()) {
//                logger.error("查帐接口异常:{},:{},:{}", commonQueryResponse.getMsg(), commonQueryResponse.getSubMsg(), commonQueryResponse.getBody());
//                return TResponse.FAIL("查帐接口异常");
//            }

            //转账单据状态
//            if (commonQueryResponse.getStatus().equals("SUCCESS")) {
//            logger.info(tenantOperator.getTenantCode() + "-" + tenantOperator.getTenantOperatorCode() + ":支付宝转账成功，准备入账:{}", alipayTransPayWalletVo.getTransAmount());

            //7 入帐
            acctWithdrawOrderService.updateSuccessAcctWithdrawOrder1(acctWithdrawOrder.getWithdrawOrderId());
//            }

//            logger.info(tenantOperator.getTenantCode() + "-" + tenantOperator.getTenantOperatorCode() + ":支付宝转帐成功:{}", alipayTransPayWalletVo.getTransAmount());

            TResponse tResponse = TResponse.SUCCESS("转帐成功");
            tResponse.put(acctWithdrawOrder);
            return tResponse;
        } catch (Exception e) {
            logger.error("支付宝转账失败异常", e);
            return TResponse.FAIL("支付宝转账失败");
        }
    }
}
